# -*- coding: utf8 -*-
from ned_app.config import Configuration
import Queue
import logging
import threading

LOGGER = logging.getLogger(__name__)

class NMJLibrary(object):
	def __init__(self, lib_id, base_dir, name, description, image):
		self.name = name
		self.description = description
		self.lib_id = lib_id
		self.image = image
		self.base_dir = base_dir

	def export(self):
		return {
			"id" : self.lib_id,
			"name" : self.name,
			"description" : self.description,
			"image" : self.image,
		}

class Command(object):
	def __init__(self, cmd, *args, **kwargs):
		self.cmd = cmd
		self.args = args
		self.kwargs = kwargs
	
	def __str__(self):
		return "%s(%s, %s)" % (self.cmd, self.args, self.kwargs)
		
	def __repr__(self):
		return "%s(%s, %s)" % (self.cmd, self.args, self.kwargs)

class NMJController(object):
	def __init__(self, conffile):
		self.config = Configuration(conffile)
		self.libs = {}
		self.updaters = {}
		self.thread = threading.Thread(target=self.run, name="NMJController")
		self._stop = False
		self.requests = Queue.Queue()
		self.replies = Queue.Queue()
		
	def start(self):
		self._stop = False
		self.thread.start()
		
	def stop(self):
		self._stop = True
		self.thread.join()

	def do_command(self, command):
		try:
			return getattr(self, command.cmd)(*command.args, **command.kwargs)
		except:
			LOGGER.exception("Cannot execute command %s", command)
			
	def get_shows(self, lib_id):
		return self.updaters[lib_id].get_shows()
	
	def get_show(self, lib_id, show_id):
		return self.updaters[lib_id].get_show(show_id=show_id)
	
	def get_video(self, lib_id, show_id):
		return self.updaters[lib_id].get_video(show_id=show_id)
	
	def get_details(self, lib_id, show_id):
		return self.updaters[lib_id].get_details(show_id=show_id)
	
	def change_poster(self, lib_id, show_id, poster):
		return self.updaters[lib_id].change_poster(show_id=show_id, poster=poster)
	
	def change_wallpaper(self, lib_id, show_id, wallpaper):
		return self.updaters[lib_id].change_wallpaper(show_id=show_id, wallpaper=wallpaper)
	
	def search(self, lib_id, video_basename):
		return self.updaters[lib_id].search(video_basename)
	
	def clean_media(self, lib_id, media):
		return self.updaters[lib_id].clean_media(media)
	
	def add_media(self, lib_id, media, new_id):
		return self.updaters[lib_id].add_media(media, new_id)
	
	def run(self):
		for name in self.config.get_libraries():
			lib_id = self.config.get_id(name)
			self.updaters[lib_id] = self.config.get_updater(name)
			self.libs[lib_id] = NMJLibrary(lib_id, self.updaters[lib_id].base_dir, name, self.config.get_description(name), self.updaters[lib_id].get_image())
		while not self._stop:
			try:
				command = self.requests.get(True, timeout=1.0)
				self.replies.put(self.do_command(command))
			except Queue.Empty:
				pass
			
			
class NMJInterface(object):
	def __init__(self, conffile):
		self.controller = NMJController(conffile)
		self.controller.start()

	def stop(self):
		self.controller.stop()
		
	def do_send(self, command, *args, **kwargs):
		self.controller.requests.put(Command(command, *args, **kwargs))
		
	def do_receive(self):
		try:
			return self.controller.replies.get(True)
		except Queue.Empty:
			return None
		
	def get_shows(self, lib_id):
		self.do_send("get_shows", lib_id)
		return self.do_receive()
	
	def get_show(self, lib_id, show_id):
		self.do_send("get_show", lib_id, show_id)
		return self.do_receive()
	
	def get_video(self, lib_id, show_id):
		self.do_send("get_video", lib_id, show_id)
		return self.do_receive()
	
	def change_poster(self, lib_id, show_id, poster):
		self.do_send("change_poster", lib_id, show_id, poster)
		return self.do_receive()
	
	def change_wallpaper(self, lib_id, show_id, wallpaper):
		self.do_send("change_wallpaper", lib_id, show_id, wallpaper)
		return self.do_receive()
	
	def search(self, lib_id, video_basename):
		self.do_send("search", lib_id, video_basename)
		return self.do_receive()
		
	def get_library(self, lib_id):
		return self.controller.libs[lib_id]

	def get_libraries(self):
		result=[]
		for lib in self.controller.libs.itervalues():
			result.append(lib.export())
		return result

	def clean_media(self, lib_id, media):
		self.do_send("clean_media", lib_id, media)
		return self.do_receive()
		
	def add_media(self, lib_id, media, new_id):
		self.do_send("add_media", lib_id, media, new_id)
		return self.do_receive()
		
	def get_details(self, lib_id, show_id):
		self.do_send("get_details", lib_id, show_id)
		return self.do_receive()
		
